package com.example.ecommercemarketing.service;

import com.example.ecommercemarketing.dto.MarketingElementsDTO;
import com.example.ecommercemarketing.dto.ProductDTO;
import com.example.ecommercemarketing.dto.UserDTO;
import com.example.ecommercemarketing.enums.ProductCategory;
import com.example.ecommercemarketing.processor.MarketingElementsProcessor;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 营销活动服务
 *
 * <p>核心服务类，负责协调不同商品大类的营销素材处理</p>
 * <p>采用策略模式，根据商品类别自动选择对应的处理器</p>
 *
 * <p>主要职责：</p>
 * <ul>
 *   <li>根据商品分类路由到对应的营销处理器</li>
 *   <li>提供统一的营销素材获取接口</li>
 *   <li>管理所有营销处理器的生命周期</li>
 * </ul>
 */
@Data
public class MarketingService {

    /**
     * 营销处理器映射表
     * <p>Key为商品大类码值，即{@link ProductCategory}枚举类中的code属性【{@link ProductCategory#getCode()}】，可由前端上送。
     * <p>Value为对应商品分类的营销处理器实例</p>
     */
    private Map<String, MarketingElementsProcessor> processorMap;

    /**
     * 获取商品营销素材
     * <p>根据商品分类选择对应的处理器，获取营销素材列表</p>
     *
     * @param category 商品大类分类枚举
     * @param products 待处理的商品列表
     * @param user 用户信息（用于个性化推荐）
     * @return 营销素材DTO列表
     * @throws IllegalArgumentException 当商品分类不支持时抛出
     *
     * @implSpec 实现步骤：
     * 1. 根据商品分类获取对应的处理器Bean名称
     * 2. 从处理器映射表中查找对应的处理器
     * 3. 如果找不到处理器则抛出异常
     * 4. 调用处理器的process方法获取营销素材
     */
    public List<MarketingElementsDTO> getMarketingElements(ProductCategory category, List<ProductDTO> products, UserDTO user) {
        //商品大类码值
        String categoryCode = category.getCode();

        // 从映射表中获取对应的处理器实例
        MarketingElementsProcessor processor = processorMap.get(categoryCode);

        // 检查处理器是否存在
        if (processor == null) {
            throw new IllegalArgumentException("Unsupported product category: " + category);
        }

        // 调用处理器获取营销素材
        return processor.process(products, user);
    }

    /**
     * 根据商品分类获取对应的处理器Bean名称
     * <p>命名规则：商品分类编码 + "MarketingProcessor"</p>
     *
     * @param category 商品分类枚举
     * @return 处理器Bean名称
     *
     * @example
     * homeAppliances → homeAppliancesMarketingProcessor
     * electronics → electronicsMarketingProcessor
     */
    private String getProcessorBeanName(ProductCategory category) {
        // 拼接商品分类编码和固定后缀
        return category.getCode() + "MarketingProcessor";
        // homeAppliances + MarketingProcessor → homeAppliancesMarketingProcessor
    }
}